package com.celeritymq.utils;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CelerityAdvisor {

	public static <T> T createProxy(Object instance, CelerityProxy celerityproxy, Class<T> clz) {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(clz);
		enhancer.setCallbacks(new Callback[] { new Interceptor(instance, celerityproxy) });
		Object proxy = enhancer.create();
		return (T) proxy;
	}

	private static class Interceptor implements MethodInterceptor {
		Object instance;
		CelerityProxy celerityproxy;

		Interceptor(Object instance, CelerityProxy celerityproxy) {
			this.instance = instance;
			this.celerityproxy = celerityproxy;
		}

		@Override
		public Object intercept(Object instance, Method method, Object[] args, MethodProxy proxy) throws Throwable {
			Object result = null;
			try {
				celerityproxy.before(instance, method, args);
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				result = proxy.invoke(this.instance, args);
			} catch (Throwable e) {
				celerityproxy.exception(e, instance, method, args);
				e.printStackTrace();
			}
			try {
				celerityproxy.after(instance, method, args);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return result;
		}
	}

}
